
#ifndef ROPUFU_MULTI_SENSOR_UNIT_TEST_TEST_INFORMATION_HPP_INCLUDED
#define ROPUFU_MULTI_SENSOR_UNIT_TEST_TEST_INFORMATION_HPP_INCLUDED

#include "../information/information_none.hpp"
#include "../information/information_exact.hpp"
#include "../information/information_at_most.hpp"

#include <array>
#include <cstddef>
#include <iostream>
#include <string>

namespace ropufu
{
    namespace unit_test
    {
        template <std::size_t t_count_streams>
        void print_masked(const std::array<char, t_count_streams>& set, const std::array<bool, t_count_streams>& mask)
        {
            std::cout << "{ ";
            for (std::size_t i = 0; i < t_count_streams; i++) if (mask[i]) std::cout << set[i];
            std::cout << " }";
        }

        template <std::size_t t_count_streams, typename t_information_type>
        bool enumerate_combinations(const std::array<char, t_count_streams>& set, const t_information_type& info)
        {
            bool is_success = true;

            std::size_t cardinality = 0;
            std::cout << info << ": cardinality = " << info.cardinality() << std::endl;
            for (const std::array<bool, t_count_streams>& mask : info)
            {
                if (cardinality != 0) std::cout << ", ";
                print_masked(set, mask);
                cardinality++;
            }
            std::cout << std::endl;
            std::cout << "# of combinations = " << cardinality << std::endl;

            if (cardinality != info.cardinality()) is_success = false;
            std::cout << (is_success ? "Passed." : "FAILED!") << std::endl;
            return is_success;
        }

        template <std::size_t t_count_streams, std::size_t t_count_affected>
        bool test_information()
        {
            bool is_success = true;
            std::array<char, t_count_streams> set;
            for (std::size_t i = 0; i < t_count_streams; i++) set[i] = 'a' + static_cast<char>(i);

            information_none<t_count_streams> inf1;
            information_exact<t_count_streams, t_count_affected> inf2;
            information_at_most<t_count_streams, t_count_affected> inf3;

            if (!enumerate_combinations(set, inf1)) is_success = false;
            if (!enumerate_combinations(set, inf2)) is_success = false;
            if (!enumerate_combinations(set, inf3)) is_success = false;

            return is_success;
        }
    }
}

#endif // ROPUFU_MULTI_SENSOR_UNIT_TEST_TEST_INFORMATION_HPP_INCLUDED
